<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>07_单线程-代码顺序如何执行</title>
  <!-- 
  在 JavaScript 中，代码的执行是单线程的，意味着在任何时刻只有一个任务在执行。这种机制影响了代码的执行顺序和异步操作的处理。
  1. 单线程模型
  - JavaScript 是单线程的，这意味着它在任何时刻只能执行一个任务。这种设计使得 JavaScript 能够避免复杂的线程管理和并发问题。
  - 单线程模型依赖于事件循环（Event Loop）来处理异步操作。

  2. 执行栈（Call Stack）
  - JavaScript 使用执行栈来管理函数调用。当一个函数被调用时，它会被推入栈中，执行完成后会被弹出。
  - 执行栈遵循后进先出（LIFO）的原则。
  function first() {
      console.log("First");
  }

  function second() {
      console.log("Second");
  }

  first(); // "First"
  second(); // "Second"
  3. 异步操作与事件循环
  - 当遇到异步操作（如  `setTimeout` 、 `fetch` 、事件监听等）时，JavaScript 将这些操作放入 Web APIs 中，异步操作完成后会将回调函数放入任务队列（Task Queue）。
  - 事件循环会不断检查执行栈是否为空，如果为空，则从任务队列中取出一个任务放入执行栈中执行。

  示例代码：
  console.log("Start");

  setTimeout(() => {
      console.log("Timeout");
  }, 0);

  console.log("End");
  输出顺序：
  Start
  End
  Timeout
  4. 微任务与宏任务
  - 在任务队列中，有微任务（Microtasks）和宏任务（Macrotasks）的区别。微任务包括 Promise 的  `.then()`  回调，而宏任务包括  `setTimeout` 、 `setInterval`  等。
  - 微任务的优先级高于宏任务，微任务会在当前任务执行完后立即执行。
  console.log("Start");

  setTimeout(() => {
      console.log("Timeout");
  }, 0);

  Promise.resolve().then(() => {
      console.log("Promise");
  });

  console.log("End");
  输出顺序：
  Start
  End
  Promise
  Timeout
  
  5. 总结
  - JavaScript 是单线程的，通过执行栈和事件循环来管理代码的执行顺序。
  - 同步代码会按照书写顺序依次执行，而异步操作会将回调函数放入任务队列，待执行栈空闲时再执行。
  - 微任务优先级高于宏任务，微任务会在当前执行上下文结束后立即执行。
  -->
</head>
<body>

  <script>
    let name = '张三';
    name = '李四';

    function fn() {
      console.log("fn函数执行: ", name); // 李四
    }

    function foo() {
      console.log("foo函数执行");
      // 1.在JavaScript内部执行
      let total = 0
      for (let i = 0; i < 100000000; i++) {
        total += i
      }
      console.log("total: ", total);
      
      // 2.创建一个定时器
      setTimeout(() => {
        console.log("setTimeout")
      }, 5000);

      fn()
    }

    foo()

  </script>
  
</body>
</html>